package sw6.visualschedule.persistence;

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.PreparedQuery;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.SelectArg;

import sw6.visualschedule.entities.Day;
import sw6.visualschedule.entities.RepeatPattern;
import sw6.visualschedule.entities.ScheduleActivity;

import android.content.Context;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

public class RepeatPatternRepo extends AbstractDataRepo<RepeatPattern> {
    
    private static final String LOG_NAME = "RepeatPatternService";
    private transient Dao<ScheduleActivity, Integer> mActivityDao;
    
    /**
     * Initializes the repository.
     * @param base the context to run in.
     */
    public RepeatPatternRepo(final Context base) {
        super(RepeatPattern.class);
        
        this.attachBaseContext(base);
        
        try {
            mActivityDao = getHelper().getDao(ScheduleActivity.class);
        } catch (SQLException e) {
        	throw new RuntimeException(LOG_NAME, e);
        }
    }
    
    /**
     * Returns a list of activities for a specific date.
     * @param date the date to filter by.
     * @return a list of activities.
     */
    public List<ScheduleActivity> getActivities(final Date date) {
        final List<ScheduleActivity> activities = new ArrayList<ScheduleActivity>();

        final Calendar calendar = GregorianCalendar.getInstance();
        calendar.setFirstDayOfWeek(GregorianCalendar.MONDAY);
        calendar.setTime(date);
        
        final Day dayInWeek = Day.fromGregorianCalendar(calendar.get(GregorianCalendar.DAY_OF_WEEK));
        
        final SelectArg dayInWeekClause = new SelectArg();
        
        try {
            final QueryBuilder<RepeatPattern, Integer> query = getDao().queryBuilder();
            
            query.selectColumns(RepeatPattern.ACTIVITY_ID_FIELD, RepeatPattern.HOUR_OF_THE_DAY_FIELD, RepeatPattern.MINUTE_OF_THE_HOUR_FIELD);
            query.where().eq(RepeatPattern.DAY_IN_WEEK_FIELD, dayInWeekClause);
            query.orderBy(RepeatPattern.HOUR_OF_THE_DAY_FIELD, true).orderBy(RepeatPattern.MINUTE_OF_THE_HOUR_FIELD, true);
            
            final PreparedQuery<RepeatPattern> preparedQuery = query.prepare();
            
            dayInWeekClause.setValue(dayInWeek);
            
            ScheduleActivity activity;
            for (RepeatPattern pattern : getDao().query(preparedQuery)) {
                activity = pattern.getActivity();

                mActivityDao.refresh(activity);
                
                calendar.set(calendar.get(GregorianCalendar.YEAR), calendar.get(GregorianCalendar.MONTH), calendar.get(GregorianCalendar.DATE), pattern.getHourOfTheDay(), pattern.getMinuteOfTheHour(), 0);
                
                activity.setInstanceDate(calendar.getTime());
                activities.add(activity);
            }
            
        } catch (SQLException e) {
        	throw new RuntimeException(LOG_NAME, e);
        }
        
        return activities;
    }
}